from apps.common.base.views import *
from apps.interface.client.models import Client
from apps.pay.order.sceneHandle import payReturnScene
from apps.pay.wx.service import getSign, aes_ecb_pkcs7
import xmltodict
import xml.etree.ElementTree as et
from django.http import HttpResponse
from apps.common.wx.wxapi import getAccessToken
from rest_framework.status import HTTP_200_OK

from apps.pay.order.dao import OrderDao

class WxPayViewSet(BaseViewSet):

    '''支付异步回调'''
    @action(methods=['post'], detail=False, authentication_classes=[],permission_classes=[])
    def paybackforMinipro(self, request):
        _xml = request.body
        #拿到微信发送的xml请求 即微信支付后的回调内容
        xml = str(_xml, encoding="utf-8")
        print("xml", xml)
        return_dict = {}
        tree = et.fromstring(xml)
        #xml 解析
        return_code = tree.find("return_code").text
        try:
            if return_code == 'FAIL':
                # 官方发出错误
                return_dict['message'] = '支付失败'
                print('支付失败')
                return Response('''<xml><return_code><![CDATA[FAIL]]></return_code><return_msg><![CDATA[支付失败]]></return_msg></xml>''', content_type='application/xml', status=HTTP_200_OK)
            elif return_code == 'SUCCESS':
                print('支付成功', tree)
                #拿到自己这次支付的 out_trade_no 
                _out_trade_no = tree.find("out_trade_no").text
                transaction_id = tree.find("transaction_id").text
                attach = tree.find("attach").text  # 额外参数
                #这里省略了 拿到订单号后的操作 看自己的业务需求
                # print('_out_trade_no', _out_trade_no, attach)
                payReturnScene('wxpay', _out_trade_no, transaction_id,'','')
                return Response('''<xml><return_code><![CDATA[SUCCESS]]></return_code><return_msg><![CDATA[OK]]></return_msg></xml>''', content_type='application/xml', status=HTTP_200_OK)
        except Exception as e:
            print('处理失败', e)
            return Response('''<xml><return_code><![CDATA[FAIL]]></return_code><return_msg><![CDATA[处理失败]]></return_msg></xml>''', content_type='application/xml', status=HTTP_200_OK)
    
    '''退款异步回调'''
    @action(methods=['post'], detail=False, authentication_classes=[],permission_classes=[])
    def returnbackforMinipro(self, request):
        _xml = request.body
        #拿到微信发送的xml请求 即微信支付后的回调内容
        xml = str(_xml, encoding="utf-8")
        print("xml", xml)
        return_dict = {}
        tree = et.fromstring(xml)
        #xml 解析
        return_code = tree.find("return_code").text
        try:
            #拿到自己这次支付的 out_trade_no 
            # base64解码
            body = base64.b64decode(tree.find("req_info").text)
            # key做md5，得到32位小写key*
            key = '70ao7jnJhtICUk01drdTYWtkLUHqXzyf'
            key = hashlib.md5(key.encode("utf8")).hexdigest()
            # key*对加密串B做AES-256-ECB解密（PKCS7Padding）
            info = aes_ecb_pkcs7(body, key)
            tree = et.fromstring(info)
            _out_trade_no = tree.find("out_trade_no").text
            #这里省略了 拿到订单号后的操作 看自己的业务需求
            print('_out_trade_no', _out_trade_no)
            # payReturnScene(attach, 'wxpay', _out_trade_no)
            order = OrderDao().findOneByOrderId(_out_trade_no)
            if return_code == 'FAIL':
                # 官方发出错误
                return_dict['message'] = '退款失败'
                print('退款失败')
                #return Response(return_dict, status=status.HTTP_400_BAD_REQUEST)
                if order.orderStatus == 'RETURNING':
                    OrderDao().update(order.id, {'orderStatus': 'RETURN_FAIL'})
                return HttpResponse(return_dict, status=10001)
            elif return_code == 'SUCCESS':
                print('退款成功')
                if order.orderStatus == 'RETURNING':
                    OrderDao().update(order.id, {'orderStatus': 'HAS_RETURN'})
                
        except Exception as e:
            pass
        finally:
            return HttpResponse(return_dict, status=200)

    '''小程序预下单接口'''
    @action(methods=['post'], detail=False)
    def createWxPayforMinipro(self, request):
        params = getRequestParams(request)
        if isEmptyStr(params.get('openid')):
            return Response(response_message('openid字段必填'))
        if isEmptyStr(params.get('clientname')):
            return Response(response_message('clientname字段必填'))
        if not params.get("orderId"):
            return Response(response_message('orderId字段必填'))
        try:
            client_model = Client.objects.get(clientname=params.get('clientname'))
            _order = OrderDao().findOneByOrderId(params.get("orderId"))
            if isEmptyStr(_order.scene):
                return Response(response_message('该订单异常，缺少scene参数'))

            # 校验积分
            if _order.realPayIncomes>0:
                if request.user.incomes < _order.realPayIncomes:
                    return Response(response_modalMessage('积分不足，支付失败'))

            r_params={}
            # 设置商品名称
            if _order.content:
                content = json.loads(_order.content)
                if content.get('orderItemList') and len(content.get('orderItemList'))>0:
                    r_params["body"] = content.get('orderItemList')[0].get('itemName')
                else:
                    r_params["body"] = "鑫珑名品优选商品"
            else:
                r_params["body"] = "鑫珑名虚拟商品"
            r_params["mch_id"] = client_model.mch_id
            r_params["appid"] = client_model.appid
            r_params["openid"] = params.get('openid')
            r_params["nonce_str"] = random_str(32)
            r_params["sign_type"] = "MD5"
            r_params['attach'] = _order.scene
            r_params["out_trade_no"] = params.get("orderId")
            r_params["notify_url"] = client_model.baseUrl + client_model.notify_url
            r_params["trade_type"] = "JSAPI"

            realPay = 0
            if client_model.realPay > 0:
                realPay = Decimal(client_model.realPay)
            else:
                realPay = _order.realPay
            
            r_params["total_fee"] = int(Decimal(realPay) * 100)

            # print('r_params',r_params)
            wxPayOrderUrl = "https://api.mch.weixin.qq.com/pay/unifiedorder"
            r_params["sign"]=getSign(r_params, client_model.mch_key)
            data = {'root': r_params}
            xml = xmltodict.unparse(data)
            res = requests.post(wxPayOrderUrl, data=xml.encode('utf-8'), headers={'Content-Type': 'text/xml'})
            xmlmsg = xmltodict.parse(res.text)
            r_data={}
            # 获取prepay_id
            if xmlmsg['xml']['return_code'] == 'SUCCESS':
                if xmlmsg['xml']['result_code'] == 'SUCCESS':
                    prepay_id = xmlmsg['xml']['prepay_id']
                    # 5个参数
                    r_data["appId"] = xmlmsg['xml']['appid']
                    r_data["nonceStr"] = xmlmsg['xml']['nonce_str']
                    r_data["package"] = "prepay_id=" + prepay_id
                    r_data["timeStamp"] = str(time.time())
                    r_data["signType"] = "MD5"
                    r_data["paySign"]=getSign(r_data, client_model.mch_key)
                    # print('r_data', r_data)
                else:
                    return_msg = xmlmsg['xml']['err_code_des'].encode('raw_unicode_escape').decode('utf-8')
                    return Response(response_message(return_msg))
            else:
                return_msg = xmlmsg['xml']['return_msg'].encode('raw_unicode_escape').decode('utf-8')
                return Response(response_message(return_msg))
        except:
            return Response(response_message('微信支付异常'))
        return Response(response_success(r_data))

    '''APP预下单接口'''
    @action(methods=['post'], detail=False)
    def createWxPayforApp(self, request):
        params = getRequestParams(request)
        if isEmptyStr(params.get('openid')):
            return Response(response_message('openid字段必填'))
        if isEmptyStr(params.get('clientname')):
            return Response(response_message('clientname字段必填'))
        if not params.get("orderId"):
            return Response(response_message('orderId字段必填'))
        
        client_model = Client.objects.get(clientname=params.get('clientname'))
        _order = OrderDao().findOneByOrderId(params.get("orderId"))
        if isEmptyStr(_order.scene):
            return Response(response_message('该订单异常，缺少scene参数'))

        r_params={}
        r_params["mch_id"] = client_model.mch_id
        r_params["appid"] = client_model.appid
        r_params["openid"] = params.get('openid')
        r_params["nonce_str"] = random_str(32)
        r_params["sign_type"] = "MD5"
        r_params["body"] = "商品购买"
        r_params['attach'] = _order.scene
        r_params["out_trade_no"] = params.get("orderId") # + random_num(5) #每次传给微信的订单号都随机，为了处理不同渠道的未支付的订单
        r_params["notify_url"] = client_model.baseUrl + client_model.notify_url
        r_params["trade_type"] = "APP"

        realPay = 0
        if client_model.realPay > 0:
            realPay = Decimal(client_model.realPay)
        else:
            _order = OrderDao().findOneByOrderId(params.get("orderId"))
            realPay = _order.realPay
        r_params["total_fee"] = int(Decimal(realPay) * 100)

        print('r_params', r_params)
        wxPayOrderUrl = "https://api.mch.weixin.qq.com/pay/unifiedorder"
        r_params["sign"]=getSign(r_params, client_model.mch_key)
        data = {'root': r_params}
        xml = xmltodict.unparse(data)
        res = requests.post(wxPayOrderUrl, data=xml.encode('utf-8'), headers={'Content-Type': 'text/xml'})
        xmlmsg = xmltodict.parse(res.text)

        # 获取prepay_id
        if xmlmsg['xml']['return_code'] == 'SUCCESS':
            if xmlmsg['xml']['result_code'] == 'SUCCESS':
                prepay_id = xmlmsg['xml']['prepay_id']
                # 5个参数
                r_data={}
                r_data["appid"] = xmlmsg['xml']['appid']
                r_data["noncestr"] = xmlmsg['xml']['nonce_str']
                r_data["package"] = "Sign=WXPay"
                r_data["partnerid"] = client_model.mch_id
                r_data["prepayid"] = prepay_id
                r_data["timestamp"] = str(time.time())
                r_data["sign"]=getSign(r_data, client_model.mch_key)
                print('r_data', r_data)
            else:
                print('return_msg', xmlmsg['xml']['err_code_des'].encode('raw_unicode_escape').decode('utf-8'))
        else:
            print('return_msg', xmlmsg['xml']['return_msg'].encode('raw_unicode_escape').decode('utf-8'))
        return Response(response_success(r_data))

    @action(methods=['post'], detail=False)
    def sendup_order(self, request):
        params = getRequestParams(request)
        res = getAccessToken({'clientname': params.get('clientname')})
        access_token = res["access_token"]
        sendOrder = 'https://api.weixin.qq.com/product/delivery/send?access_token=' + access_token
        headers = {'content-type': "application/json", 'Accept': "application/json",}
        data = {
            "order_id": "sadsd"
        }
        res = requests.post(sendOrder, data=json.dumps(data), headers=headers,)
        res_content = json.loads(res.content)
        print('res_content', res_content)
        return Response(response_message('微信支付异常'))